package com.hjx.movie.core.system.service.admin.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hjx.movie.common.utils.ResultType;
import com.hjx.movie.common.utils.exceptions.CustomException;
import com.hjx.movie.core.system.service.admin.IRoleMenuService;
import com.hjx.movie.core.util.cache.CacheKey;
import com.hjx.movie.core.util.cache.CacheUtil;
import com.hjx.movie.persistence.system.mapper.IvyRoleMenuMapper;
import com.hjx.movie.persistence.system.model.IvyRoleMenu;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>Title:</p>
 * <p>Description:</p>
 *
 * @author hjx
 * @date 2021/1/25 - 17:44
 */
@Slf4j
@Service
@Transactional
@CacheConfig(cacheNames = "IvyMovie:SpringCache:RoleMenuCache",keyGenerator = "cacheKeyGenerator")
public class RoleMenuService extends ServiceImpl<IvyRoleMenuMapper, IvyRoleMenu> implements IRoleMenuService {
    @Resource
    private CacheUtil<IvyRoleMenu> cacheUtil;
    public static final String ROLE_MENU_KEY = CacheUtil.cacheNameFormat(CacheKey.SYSTEM.getName(),CacheKey.ROLE_MENU.getName());
    public static final String ROLE_MENU_CACHE_DATA = CacheUtil.cacheNameFormat(CacheKey.SYSTEM.getName(),CacheKey.ROLE_MENU.getName(),CacheKey.PRE_SAVE_ROLE_MENU.getName());

    @Cacheable(unless = "#result==null")
    @Override
    public List<Long> findMenuByRoleId(Long roleId) {
        List<IvyRoleMenu> roleMenus = cacheUtil.getCacheList(ROLE_MENU_CACHE_DATA);
        return roleMenus.stream().filter(item->item.getRoleId().equals(roleId))
                .map(IvyRoleMenu::getMenuId).collect(Collectors.toList());
    }
    //IvyMovie:SpringCache:RoleMenuCache::com.hjx.movie.core.system.service.admin.impl.RoleMenuService:findMenuByRoleId:3
    @CacheEvict(value = "IvyMovie:SpringCache:RoleMenuCache",
            key="'com.hjx.movie.core.system.service.admin.impl.RoleMenuService:findMenuByRoleId:'+#roleId",
            beforeInvocation = true)
    @Override
    public boolean addOrDeleteMenuBatch(Long roleId, Set<Long> menuIds) {
        List<IvyRoleMenu> roleMenus = cacheUtil.getCacheList(ROLE_MENU_CACHE_DATA);
        Set<Long> rawMenus =  roleMenus.stream()
                .filter(item->item.getRoleId().equals(roleId))
                .map(IvyRoleMenu::getMenuId).collect(Collectors.toSet());
        addRoleMenuBatch(roleId,menuIds,rawMenus);
        deleteRoleMenuBatch(roleId,menuIds,rawMenus);
        return true;
    }

    public void addRoleMenuBatch(Long roleId, Set<Long> menuIds,Set<Long> rawMenus) {
        Set<Long> copyMenuIds = new HashSet<>(menuIds);
        Set<Long> copyRawMenuIds = new HashSet<>(rawMenus);
        // Set集合做差集 获取新增的apiId
        copyMenuIds.removeAll(copyRawMenuIds);
        if (copyMenuIds.isEmpty()) {
            return;
        }
        log.debug("新增角色菜单权限入参===>角色标识:{},新增的菜单标识为:{}",roleId,copyMenuIds);
        List<IvyRoleMenu> addRoleMenus = copyMenuIds.stream().map(menuId -> {
            IvyRoleMenu ra = new IvyRoleMenu();
            ra.setRoleId(roleId);
            ra.setMenuId(menuId);
            ra.setStatus(true);
            return ra;
        }).collect(Collectors.toList());
        if(saveBatch(addRoleMenus)){
            for (IvyRoleMenu roleMenu:addRoleMenus){
                cacheUtil.getOpsForHash().put(ROLE_MENU_CACHE_DATA,roleMenu.getRoleMenuId().toString(),roleMenu);
            }
        }else {
            throw new CustomException(ResultType.USER_INPUT_ERROR,"角色新增菜单权限失败");
        }
}

    public void deleteRoleMenuBatch(Long roleId, Set<Long> menuIds,Set<Long> rawMenus) {
        Set<Long> copyMenuIds = new HashSet<>(menuIds);
        Set<Long> copyRawMenuIds = new HashSet<>(rawMenus);
        copyRawMenuIds.removeAll(copyMenuIds);
        if (copyRawMenuIds.isEmpty()){
            return;
        }
        log.debug("删除角色菜单权限入参===>角色标识:{},删除的菜单标识为:{}",roleId,copyRawMenuIds);
        List<IvyRoleMenu> roleMenus = cacheUtil.getCacheList(ROLE_MENU_CACHE_DATA);
        List<String> removeMenuIds = roleMenus.stream()
                .filter(item ->item.getRoleId().equals(roleId)&&copyRawMenuIds.contains(item.getMenuId()))
                .map(item -> item.getRoleMenuId().toString()).collect(Collectors.toList());
        if (removeByIds(removeMenuIds)){
            cacheUtil.getOpsForHash().delete(ROLE_MENU_CACHE_DATA, removeMenuIds.toArray());
        }else {
            throw new CustomException(ResultType.USER_INPUT_ERROR,"角色删除菜单权限失败");
        }
    }

}
